import pygame
import sys
import os
from particle import ParticleSystem
from heart import Heart
from sound_manager import SoundManager

class LoveParticles:
    def __init__(self):
        """初始化爱心粒子效果程序"""
        # 初始化Pygame
        pygame.init()
        pygame.mixer.init()  # 初始化音频系统
        
        # 初始化声音管理器
        self.sound_manager = SoundManager()
        self._setup_audio()
        
        # 设置窗口
        self.width = 800
        self.height = 600
        self.screen = pygame.display.set_mode((self.width, self.height))
        pygame.display.set_caption("520 爱心粒子效果 - 按H显示帮助")
        
        # 创建用于绘制轨迹的surface
        self.trail_surface = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
        self.trail_surface.set_alpha(100)  # 设置轨迹透明度
        
        # 加载字体
        try:
            # 尝试加载不同大小的字体
            self.large_font = pygame.font.Font(None, 120)
            self.medium_font = pygame.font.Font(None, 48)
            self.small_font = pygame.font.Font(None, 24)
        except pygame.error:
            print("警告：无法加载字体")
            self.large_font = None
            self.medium_font = None
            self.small_font = None
            
        # 动画计时器
        self.animation_timer = 0
        self.show_text = True  # 文字闪烁控制
        
        # 渐变色背景
        self.gradient_colors = [
            (30, 0, 30),   # 深紫色
            (60, 0, 60),   # 紫色
            (30, 0, 30)    # 深紫色
        ]
        self.gradient_pos = 0
        
        # 初始化时钟
        self.clock = pygame.time.Clock()
        
        # 创建粒子系统
        self.particle_system = ParticleSystem()
        
        # 设置背景颜色
        self.bg_color = (30, 30, 30)  # 深灰色背景
        
        # 鼠标跟踪变量
        self.last_mouse_pos = None
        self.mouse_moved = False
        
        # 显示帮助信息
        self.show_help = False
        
        # 特效模式
        self.effect_mode = "normal"  # normal, spiral, explosion
        
        # 加载字体
        try:
            self.font = pygame.font.Font(None, 24)  # 使用默认字体
        except pygame.error:
            print("警告：无法加载字体，帮助文本可能无法正确显示")
            self.font = None
            
        # 创建帮助文本
        self.help_text = [
            "控制键:",
            "H - 显示/隐藏帮助",
            "1-3 - 切换颜色模式（粉色/彩虹/金色）",
            "Q/W/E - 切换粒子样式（普通/星星/爱心）",
            "S - 切换特效模式（普通/螺旋/爆炸）",
            "空格 - 触发全屏特效",
            "M - 开关背景音乐",
            "N - 开关音效",
            "↑/↓ - 调整音量",
            "Esc - 退出程序"
        ]
        
        # 音量控制
        self.volume = 0.5
        
    def handle_events(self):
        """处理事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            elif event.type == pygame.MOUSEMOTION:
                # 记录鼠标移动
                self.mouse_moved = True
                self.last_mouse_pos = event.pos
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 鼠标点击时生成大量粒子形成爱心形状
                x, y = event.pos
                self._create_heart_particles(x, y)
                self.sound_manager.play_sound('click')
            elif event.type == pygame.KEYDOWN:
                self._handle_keypress(event.key)
                
        return True
        
    def _setup_audio(self):
        """设置音频文件"""
        # 创建sounds目录（如果不存在）
        sounds_dir = os.path.join(os.path.dirname(__file__), 'sounds')
        os.makedirs(sounds_dir, exist_ok=True)
        
        # 定义默认的音效文件
        default_sounds = {
            'click': 'click.wav',
            'special': 'special.wav',
            'background': 'background.mp3'
        }
        
        # 检查音效文件是否存在，如果不存在则创建提示
        missing_sounds = []
        for sound_name, filename in default_sounds.items():
            path = os.path.join(sounds_dir, filename)
            if not os.path.exists(path):
                missing_sounds.append(filename)
                
        if missing_sounds:
            print("\n请注意：以下音效文件不存在，需要添加到 src/sounds 目录：")
            for filename in missing_sounds:
                print(f"- {filename}")
            print("\n您可以使用自己的音效文件，或从网上下载免费音效。")
            print("音效文件格式要求：")
            print("- 点击音效 (click.wav): 简短的点击音效")
            print("- 特效音效 (special.wav): 特效触发时的音效")
            print("- 背景音乐 (background.mp3): 循环播放的背景音乐")
        else:
            # 如果文件存在，加载音效
            self.sound_manager.load_sound('click', os.path.join(sounds_dir, 'click.wav'))
            self.sound_manager.load_sound('special', os.path.join(sounds_dir, 'special.wav'))
            self.sound_manager.load_music(os.path.join(sounds_dir, 'background.mp3'))
            
            # 设置初始音量
            self.sound_manager.set_music_volume(self.volume)
            self.sound_manager.play_music()
            
    def _handle_keypress(self, key):
        """处理键盘按键事件"""
        # 音频控制
        if key == pygame.K_m:
            self.sound_manager.toggle_music()
        elif key == pygame.K_n:
            self.sound_manager.toggle_sound()
        elif key == pygame.K_UP:
            self.volume = min(1.0, self.volume + 0.1)
            self.sound_manager.set_music_volume(self.volume)
        elif key == pygame.K_DOWN:
            self.volume = max(0.0, self.volume - 0.1)
            self.sound_manager.set_music_volume(self.volume)
        if key == pygame.K_ESCAPE:
            pygame.quit()
            sys.exit()
        elif key == pygame.K_h:
            self.show_help = not self.show_help
        elif key == pygame.K_1:
            self.particle_system.set_color_mode("pink")
        elif key == pygame.K_2:
            self.particle_system.set_color_mode("rainbow")
        elif key == pygame.K_3:
            self.particle_system.set_color_mode("gold")
        elif key == pygame.K_q:
            self.particle_system.set_particle_style("normal")
        elif key == pygame.K_w:
            self.particle_system.set_particle_style("star")
        elif key == pygame.K_e:
            self.particle_system.set_particle_style("heart")
        elif key == pygame.K_s:
            self._cycle_effect_mode()
        elif key == pygame.K_SPACE:
            self._trigger_special_effect()
            
    def _cycle_effect_mode(self):
        """循环切换特效模式"""
        modes = ["normal", "spiral", "explosion"]
        current_index = modes.index(self.effect_mode)
        self.effect_mode = modes[(current_index + 1) % len(modes)]
        
    def _trigger_special_effect(self):
        """触发全屏特效"""
        self.sound_manager.play_sound('special')
        if self.effect_mode == "spiral":
            self._create_spiral_effect()
        elif self.effect_mode == "explosion":
            self._create_explosion_effect()
        else:
            self._create_rain_effect()
            
    def _create_spiral_effect(self):
        """创建螺旋特效"""
        center_x = self.width // 2
        center_y = self.height // 2
        points = 200
        spirals = 3  # 同时创建多个螺旋
        
        for spiral in range(spirals):
            spiral_offset = (2 * math.pi * spiral) / spirals
            for i in range(points):
                angle = (i / points) * math.pi * 10 + spiral_offset
                radius = i * 2
                x = center_x + math.cos(angle) * radius
                y = center_y + math.sin(angle) * radius
                # 添加轨迹效果
                self.particle_system.emit(x, y, 2, trail_length=10, spread=0.5)
            
    def _create_explosion_effect(self):
        """创建爆炸特效"""
        center_x = self.width // 2
        center_y = self.height // 2
        
        # 创建多层爆炸效果
        layers = 4
        for layer in range(layers):
            particles_per_layer = 50
            radius = 50 * (layer + 1)
            
            for i in range(particles_per_layer):
                angle = (i / particles_per_layer) * math.pi * 2
                x = center_x + math.cos(angle) * radius
                y = center_y + math.sin(angle) * radius
                # 添加轨迹效果，扩散程度随层数增加
                spread = 1.0 + layer * 0.5
                self.particle_system.emit(x, y, 3, trail_length=15, spread=spread)
            
    def _create_rain_effect(self):
        """创建下雨特效"""
        # 创建多层雨效果
        layers = 3
        for layer in range(layers):
            height = -100 * layer  # 不同高度开始
            for _ in range(20):
                x = random.uniform(0, self.width)
                y = height + random.uniform(-50, 50)
                # 轨迹长度随层数增加
                trail_length = 5 + layer * 5
                self.particle_system.emit(x, y, 2, trail_length=trail_length)
    
    def _create_heart_particles(self, x, y, size=20):
        """在指定位置创建爱心形状的粒子"""
        # 在轨迹surface上绘制半透明的爱心
        heart_points = Heart.generate_points(x, y, size)
        if len(heart_points) >= 3:  # 确保有足够的点来绘制
            pygame.draw.polygon(self.trail_surface, (255, 192, 203, 100),
                             heart_points)
        
        # 创建爱心轮廓粒子
        outline_points = Heart.generate_points(x, y, size)
        for point in outline_points:
            self.particle_system.emit(*point, 2, trail_length=5)
        
        # 创建爱心填充粒子
        fill_points = Heart.generate_fill_points(x, y, size, density=0.3)
        for point in fill_points:
            self.particle_system.emit(*point, 1, trail_length=3)
            
        # 创建向外扩散的装饰粒子
        decoration_count = 12
        for i in range(decoration_count):
            angle = (i / decoration_count) * math.pi * 2
            dist = size * 1.2
            dx = math.cos(angle) * dist
            dy = math.sin(angle) * dist
            self.particle_system.emit(x + dx, y + dy, 3, trail_length=8, spread=1.5)
        
        Args:
            x (int): 爱心中心x坐标
            y (int): 爱心中心y坐标
            size (int): 爱心大小
        """
        # 生成爱心轮廓点
        outline_points = Heart.generate_points(x, y, size)
        # 生成爱心填充点
        fill_points = Heart.generate_fill_points(x, y, size)
        
        # 在轮廓点上生成粒子
        for point in outline_points:
            self.particle_system.emit(*point, 3)
        
        # 在填充点上生成粒子
        for point in fill_points:
            self.particle_system.emit(*point, 1)
    
    def update(self):
        """更新游戏状态"""
        # 更新粒子系统
        self.particle_system.update()
        
        # 如果鼠标移动，在鼠标位置生成粒子
        if self.mouse_moved and self.last_mouse_pos:
            self.particle_system.emit(*self.last_mouse_pos, 2)
            self.mouse_moved = False
    
    def draw(self):
        """绘制画面"""
        # 绘制渐变背景
        self._draw_gradient_background()
        
        # 绘制装饰边框
        self._draw_decorative_border()
        
        # 绘制粒子轨迹
        self.screen.blit(self.trail_surface, (0, 0))
        
        # 绘制粒子
        self.particle_system.draw(self.screen)
        
        # 绘制动态文字
        self._draw_animated_text()
        
        # 绘制帮助信息
        if self.show_help and self.small_font:
            for i, line in enumerate(self.help_text):
                text_surface = self.small_font.render(line, True, (255, 255, 255))
                self.screen.blit(text_surface, (10, 10 + i * 25))
        
        # 更新显示
        pygame.display.flip()
        
        # 更新动画计时器
        self.animation_timer = (self.animation_timer + 1) % 60
        if self.animation_timer % 30 == 0:
            self.show_text = not self.show_text
            
    def _draw_gradient_background(self):
        """绘制渐变背景"""
        # 更新渐变位置
        self.gradient_pos = (self.gradient_pos + 0.5) % self.height
        
        for y in range(self.height):
            # 计算当前位置的颜色
            rel_pos = ((y + self.gradient_pos) % self.height) / self.height
            if rel_pos < 0.5:
                t = rel_pos * 2
                color = self._interpolate_color(
                    self.gradient_colors[0],
                    self.gradient_colors[1],
                    t
                )
            else:
                t = (rel_pos - 0.5) * 2
                color = self._interpolate_color(
                    self.gradient_colors[1],
                    self.gradient_colors[2],
                    t
                )
            # 绘制一行渐变色
            pygame.draw.line(self.screen, color, (0, y), (self.width, y))
            
    def _interpolate_color(self, color1, color2, t):
        """在两个颜色之间进行插值"""
        return tuple(int(c1 + (c2 - c1) * t) for c1, c2 in zip(color1, color2))
        
    def _draw_decorative_border(self):
        """绘制装饰边框"""
        border_width = 2
        padding = 10
        
        # 绘制外边框
        pygame.draw.rect(self.screen, (255, 255, 255),
                        (padding, padding,
                         self.width - 2 * padding,
                         self.height - 2 * padding),
                        border_width)
        
        # 绘制角落的装饰
        corner_size = 20
        for x, y in [(padding, padding),
                     (self.width - padding - corner_size, padding),
                     (padding, self.height - padding - corner_size),
                     (self.width - padding - corner_size,
                      self.height - padding - corner_size)]:
            # 绘制装饰性的小爱心或星星
            pygame.draw.rect(self.screen, (255, 192, 203),
                           (x, y, corner_size, corner_size), 1)
            
    def _draw_animated_text(self):
        """绘制动画文字"""
        if not self.large_font or not self.medium_font:
            return
            
        # 计算文字位置
        center_x = self.width // 2
        center_y = self.height // 2
        
        # 绘制主标题 "520"
        if self.show_text:
            text_surface = self.large_font.render("520", True, (255, 192, 203))
            text_rect = text_surface.get_rect(center=(center_x, center_y - 100))
            self.screen.blit(text_surface, text_rect)
        
        # 绘制浪漫文字
        love_text = "Love Forever"
        text_surface = self.medium_font.render(love_text, True,
                                             (255, 255, 255))
        text_rect = text_surface.get_rect(center=(center_x, self.height - 50))
        self.screen.blit(text_surface, text_rect)
        
        # 根据动画计时器计算缩放比例
        scale = 1.0 + 0.1 * math.sin(self.animation_timer * 0.1)
        
        # 在鼠标位置附近显示小文字
        if self.last_mouse_pos:
            mouse_text = "♥"
            text_surface = self.medium_font.render(mouse_text, True,
                                                 (255, 192, 203))
            # 缩放文字
            orig_size = text_surface.get_size()
            new_size = (int(orig_size[0] * scale), int(orig_size[1] * scale))
            scaled_surface = pygame.transform.scale(text_surface, new_size)
            # 绘制文字
            text_rect = scaled_surface.get_rect(
                center=(self.last_mouse_pos[0], self.last_mouse_pos[1] - 30)
            )
            self.screen.blit(scaled_surface, text_rect)
    
    def run(self):
        """运行主循环"""
        running = True
        while running:
            # 处理事件
            running = self.handle_events()
            
            # 更新游戏状态
            self.update()
            
            # 绘制画面
            self.draw()
            
            # 控制帧率
            self.clock.tick(60)
        
        # 退出程序
        pygame.quit()
        sys.exit()

if __name__ == "__main__":
    # 创建并运行程序
    app = LoveParticles()
    app.run()